package org.jeecg.modules.api.wxapi;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.api.client.util.Maps;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.util.DateUtils;
import org.jeecg.modules.api.wxapi.form.ListForm;
import org.jeecg.modules.api.wxapi.form.LoginForm;
import org.jeecg.modules.enums.DelFlagEnum;
import org.jeecg.modules.enums.StatusEnum;
import org.jeecg.modules.golf.document.entity.PDFDocument;
import org.jeecg.modules.golf.document.enums.PDFDocumentTypeEnum;
import org.jeecg.modules.golf.document.service.IPDFDocumentService;
import org.jeecg.modules.golf.plan.entity.Plan;
import org.jeecg.modules.golf.plan.entity.PlanTypeMapping;
import org.jeecg.modules.golf.plan.service.IPlanService;
import org.jeecg.modules.golf.plan.service.IPlanTypeMappingService;
import org.jeecg.modules.golf.question.client.QuestionPage;
import org.jeecg.modules.golf.question.client.qto.QuestionQueryPageDTO;
import org.jeecg.modules.golf.question.entity.MyQuestionPlan;
import org.jeecg.modules.golf.question.entity.PlanEffective;
import org.jeecg.modules.golf.question.entity.Question;
import org.jeecg.modules.golf.question.entity.QuestionTypeMapping;
import org.jeecg.modules.golf.question.query.QuestionQueryService;
import org.jeecg.modules.golf.question.service.*;
import org.jeecg.modules.golf.tag.entity.TagMapping;
import org.jeecg.modules.golf.tag.service.ITagMappingService;
import org.jeecg.modules.golf.utils.AES;
import org.jeecg.modules.golf.utils.HttpUtil;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.service.ISysUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 微信api接口
 */
@RestController
@RequestMapping("/wxapi")
@Slf4j
public class WxApiController {
    private Logger logger = LoggerFactory.getLogger(WxApiController.class);

    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private IQuestionService questionService;
    @Autowired
    private IPDFDocumentService ipdfDocumentService;
    @Autowired
    private QuestionQueryService questionQueryService;
    @Autowired
    private ITagMappingService iTagMappingService;
    @Autowired
    private IQuestionTypeService iQuestionTypeService;
    @Autowired
    private IQuestionTypeMappingService iQuestionTypeMappingService;
    @Autowired
    private IMyQuestionPlanService iMyQuestionPlanService;
    @Autowired
    private IPlanService iPlanService;
    @Autowired
    private IPlanEffectiveService planEffectiveService;
    @Autowired
    private IPlanTypeMappingService iPlanTypeMappingService;


    @Value("${wx.appid}")
    private String appid;

    @Value("${wx.secret}")
    private String secret;

    /**
     * 微信登陆
     * @param loginForm
     * @return
     */
    @AutoLog(value = "微信-手机号登录")
    @ApiOperation(value="微信-手机号登录", notes="微信-手机号登录")
    @GetMapping(value = "/login")
    public Result<?> login(LoginForm loginForm) {
        Result result = Result.OK();
        try {
            String wxresult = HttpUtil.doGet("https://api.weixin.qq.com/sns/jscode2session?appid="+appid+"&secret="+secret+"&js_code="+loginForm.getCode()+"&grant_type=authorization_code");

            //数据处理
            JSONObject obj = JSONUtil.parseObj(wxresult);
            String session_key = obj.getStr("session_key");
            if(StringUtils.isEmpty(session_key)) {
                throw new Exception("无效登录");
            }
            String wxLoginAxis = AES.wxDecrypt(loginForm.getEncryptedData(), session_key, loginForm.getIv());
            JSONObject wxLoginAxisObj = JSONUtil.parseObj(wxLoginAxis);
            String mobile = wxLoginAxisObj.getStr("phoneNumber");
            if(StringUtils.isEmpty(mobile)) {
                throw new Exception("用户不存在");
            }
            SysUser sysUser = sysUserService.getOne(new QueryWrapper<SysUser>().lambda()
                    .eq(SysUser::getPhone, mobile).eq(SysUser::getDelFlag, DelFlagEnum.TRUE.getCode()));
            if(sysUser == null) {
                throw new Exception("用户不存在");
            }
            if(StatusEnum.FROZEN.getCode() == sysUser.getStatus()) {
                throw new Exception("账号冻结无法登录");
            }
            result.setResult(sysUser);
        } catch (Exception e) {
            result = Result.error(e.getMessage());
        }
        return result;
    }

    /**
     * 列表
     * @param listForm
     * @return
     */
    @AutoLog(value = "微信-问题列表")
    @ApiOperation(value="微信-问题列表", notes="微信-问题列表")
    @GetMapping(value = "/list")
    public Result<?> list(ListForm listForm){
        Result result = Result.OK();
        //根据手机号查询用户
        SysUser sysUser = sysUserService.getUserByPhone(listForm.getMobile());

        if(listForm.getType() <= 3) {
            QuestionQueryPageDTO questionQueryPageDTO = new QuestionQueryPageDTO();
            if(listForm.getType() > 0) {
                questionQueryPageDTO.setQuestionStatus((listForm.getType() == 1 ? "2" : listForm.getType() == 2 ? "1" : "0"));
            }
            questionQueryPageDTO.setSize(listForm.getPageSize());
            questionQueryPageDTO.setCurrent(listForm.getPageNo());
            questionQueryPageDTO.setTrainee(sysUser.getId());

            IPage<QuestionPage> pageList = questionQueryService.page(questionQueryPageDTO);

            Map<String, Map<String, List<QuestionPage>>> map = new HashMap<>();
            pageList.getRecords().forEach(i->{
                String yyyy = DateUtils.formatDate(i.getCreateTime(), "yyyy")+"年";
                String mm = DateUtils.formatDate(i.getCreateTime(), "MM")+"月";

                if(map.containsKey(yyyy)) {
                    Map<String, List<QuestionPage>> mmMap = map.get(yyyy);
                    if(mmMap.containsKey(mm)) {
                        List<QuestionPage> questionList = mmMap.get(mm);
                        questionList.add(i);
                        mmMap.put(mm, questionList);
                        map.put(yyyy, mmMap);
                    }else {
                        List<QuestionPage> questionList = new ArrayList<>();
                        questionList.add(i);
                        mmMap.put(mm, questionList);
                        map.put(yyyy, mmMap);
                    }

                }else {
                    Map<String, List<QuestionPage>> mmMap = new HashMap<>();
                    List<QuestionPage> questionList = new ArrayList<>();
                    questionList.add(i);
                    mmMap.put(mm, questionList);
                    map.put(yyyy, mmMap);
                }
            });

            for(String key: map.keySet()) {
                Map<String, List<QuestionPage>> oldZMap = map.get(key);
                map.put(key, sortByKey(oldZMap, true));
            }

            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("data", sortByKey(map, true));
            resultMap.put("pageNo", listForm.getPageNo());
            if(map.size()==0){
                resultMap.put("length",0);

            }
            result.setResult(resultMap);
        }else if(listForm.getType() == 4){
            result.setResult(census(sysUser.getId()));
        }else if(listForm.getType() == 5){
            result.setResult(ipdfDocumentService.list(new QueryWrapper<PDFDocument>().lambda()
                    .eq(PDFDocument::getObjectId, sysUser.getId())
                    .eq(PDFDocument::getObjectType, PDFDocumentTypeEnum.USER.getCode())));
        }

        return result;
    }

    /**
     * 根据map的key排序
     *
     * @param map 待排序的map
     * @param isDesc 是否降序，true：降序，false：升序
     * @return 排序好的map
     * @author zero 2019/04/08
     */
    public static <K extends Comparable<? super K>, V> Map<K, V> sortByKey(Map<K, V> map, boolean isDesc) {
        Map<K, V> result = Maps.newLinkedHashMap();
        if (isDesc) {
            map.entrySet().stream().sorted(Map.Entry.<K, V>comparingByKey().reversed())
                    .forEachOrdered(e -> result.put(e.getKey(), e.getValue()));
        } else {
            map.entrySet().stream().sorted(Map.Entry.<K, V>comparingByKey())
                    .forEachOrdered(e -> result.put(e.getKey(), e.getValue()));
        }
        return result;
    }

    public Map<String, Object> census(String userid){
        //查询已解决问题
        LambdaQueryWrapper<Question> paramter =new QueryWrapper<Question>().lambda().eq(Question::getTrainee, userid);
        paramter.eq(Question::getQuestionStatus, 2);
        Integer resolved = questionService.count(paramter);
        //查询已出方案问题
        paramter =new QueryWrapper<Question>().lambda().eq(Question::getTrainee, userid);
        paramter.eq(Question::getQuestionStatus, 1);
        Integer programme = questionService.count(paramter);
        //查询未解决问题
        paramter =new QueryWrapper<Question>().lambda().eq(Question::getTrainee, userid);
        paramter.eq(Question::getQuestionStatus, 0);
        Integer unresolved = questionService.count(paramter);
        //高频问题分类
        List<Map<String, String>> typeMap = iQuestionTypeService.queryTypeByUserId(userid);
        //标签
        List<Map<String, String>> tagMap = iTagMappingService.queryTagByGroup(userid);

        Map<String, Object> map = new HashMap<>();
        map.put("resolved", resolved);
        map.put("unresolved", unresolved);
        map.put("programme", programme);
        map.put("typeMap", typeMap);
        map.put("tagMap", tagMap);
        return map;
    }

    @AutoLog(value = "微信-问题详情")
    @ApiOperation(value="微信-问题详情", notes="微信-问题详情")
    @GetMapping(value = "/question/details")
    public Result<?> details(ListForm listForm){

        Question question = questionService.getById(listForm.getQuestionId());

        //查询分类
        List<TagMapping> tagList = iTagMappingService.list(new QueryWrapper<TagMapping>().lambda()
                .eq(TagMapping::getMappingId, question.getId())
                .eq(TagMapping::getMappingType, 1));
        //查询标签
        List<Long> idList = new ArrayList<>();
        idList.add(question.getId());
        List<QuestionTypeMapping> typeList = iQuestionTypeMappingService.selectByMappingIdList(idList, 1);

        //查询方案
        List<MyQuestionPlan> myQuestionPlanList = iMyQuestionPlanService.selectByMainId(question.getId());
        List<Plan> planList = new ArrayList<>();
        if(myQuestionPlanList.size() > 0) {
            planList = iPlanService.list(new QueryWrapper<Plan>().lambda()
                    .in(Plan::getId, myQuestionPlanList.stream().map(MyQuestionPlan::getPlanId).collect(Collectors.toList())));
        }

        //查询效果
        List<PlanEffective> planEffectivesList = planEffectiveService.list(new QueryWrapper<PlanEffective>()
                .lambda().eq(PlanEffective::getQuestionId, question.getId()));

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("data", question);
        resultMap.put("tagList", tagList);
        resultMap.put("typeList", typeList);
        resultMap.put("planList", planList);
        resultMap.put("planEffectivesList", planEffectivesList);
        return Result.OK(resultMap);
    }

    @AutoLog(value = "微信-方案详情")
    @ApiOperation(value="微信-方案详情", notes="微信-方案详情")
    @GetMapping(value = "/plan/details")
    public Result<?> planDetails(ListForm listForm){
        Plan plan = iPlanService.getById(listForm.getPlanId());

        //方案分类
        List<PlanTypeMapping> planTypeMappingList = iPlanTypeMappingService.list(new QueryWrapper<PlanTypeMapping>().lambda()
                .eq(PlanTypeMapping::getPlanId, plan.getId()));

        //标签
        List<TagMapping> tagMappingList = iTagMappingService.list(new QueryWrapper<TagMapping>().lambda()
                .eq(TagMapping::getMappingId, plan.getId())
                .eq(TagMapping::getMappingType, 2));

        //通过方案id 查询问题
        List<MyQuestionPlan> myQuestionPlanList = iMyQuestionPlanService.list(new QueryWrapper<MyQuestionPlan>().lambda()
                .eq(MyQuestionPlan::getPlanId, plan.getId()));
        //查询问题分类
        Set<String> typeSet = new HashSet<>();
        if(myQuestionPlanList.size() > 0){
            List<QuestionTypeMapping> questionTypeMappingList = iQuestionTypeMappingService.selectByMappingIdList(myQuestionPlanList.stream().map(MyQuestionPlan::getQuestionId).collect(Collectors.toList()), 1);
            typeSet = questionTypeMappingList.stream().map(QuestionTypeMapping::getQuestionTypeName).collect(Collectors.toSet());
        }

        //根据方案id 查询附件
        List<PDFDocument> pdfList = ipdfDocumentService.list(new QueryWrapper<PDFDocument>()
                .lambda()
                .eq(PDFDocument::getObjectType, PDFDocumentTypeEnum.PLAN.getCode())
                .eq(PDFDocument::getObjectId, plan.getId()));

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("data", plan);
        resultMap.put("pdfList", pdfList);
        resultMap.put("planTypeMappingList", planTypeMappingList);
        resultMap.put("tagMappingList", tagMappingList);
        resultMap.put("typeList", typeSet);
        return Result.OK(resultMap);
    }
}
